/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bllImplement;

import bllInterface.BLLChatServer;
import bllInterface.BLLFileServer;
import bllInterface.ChatMessage;
import bllInterface.ChatMessageContent;
import bllInterface.FileMessage;
import bllInterface.iChatUser;
import dalfactory.SDALFactory;
import java.rmi.RemoteException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Mrkupi
 */
public class BLLChatServerImpl implements BLLChatServer {

    private final Map<String, iChatUser> users = new HashMap<>();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    private BLLFileServer fileServer;
    
    public BLLChatServerImpl() throws RemoteException
    {
        fileServer = new BLLFileServerImpl();
    }
    
    @Override
    public boolean login(iChatUser user) throws RemoteException
    {
        synchronized (user)
        {
            this.users.put(user.getChatID(), user);
        }

        return true;
    }

    @Override
    public boolean logout(iChatUser user) throws RemoteException
    {
        synchronized (user)
        {
            if (this.users.containsKey(user.getChatID()))
            {
                this.users.remove(user.getChatID());

                return true;
            }
        }

        return false;
    }

    @Override
    public void post(final ChatMessage cm) throws RemoteException {
        iChatUser receiver;
        if (!cm.getContent().containsKey(ChatMessageContent.TIME))
        {
            cm.getContent().put(ChatMessageContent.TIME, Calendar.getInstance().getTime());
        }
        
        if(cm.isNeedToSave() && !cm.isFile())
        {
            Thread t = new Thread(){
                @Override
                public void run(){
                    try{
                        SDALFactory.getInstance().getMessage().addNewMessage(cm);
                    } catch (RemoteException ex){
                        Logger.getLogger(BLLChatServerImpl.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            };
            t.start();
        }
        
        synchronized(users)
        {
            if(cm.getReceiver() == null)
                receiver = users.get("0");
            else 
                receiver = users.get(cm.getReceiver());
        }
        try{
            if(receiver != null)
                receiver.onHasMessage(cm);
        }
        catch (RemoteException ex)
        {
            Logger.getLogger(BLLChatServerImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void postVoice( String sender, String receiver, byte[] pack ) throws RemoteException {
        iChatUser greceiver  =   null;
        
        synchronized(users)
        {
            if(receiver != null)
                greceiver = users.get(receiver);
        }
        try{
            if(greceiver != null)
                greceiver.onHasVoice(sender, receiver, pack);
        }
        catch (RemoteException ex)
        {
            Logger.getLogger(BLLChatServerImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    @Override
    public void postFile(String fileName, FileMessage fm) throws RemoteException {
        fileServer.upFile(fileName, fm);
        ChatMessage cm = ChatMessage.createMessage(fm.getSender(), fm.getName(), fm.getReceiver());
        cm.setIsFile(true);
        post(cm);
    }

    @Override
    public FileMessage getFile(String fileName) throws RemoteException {
        return fileServer.downFile(fileName);
    }

    @Override
    public void changeKey(String user, String sender) throws RemoteException {
        synchronized(users)
        {
            if( users.containsKey(user) )
            {
                iChatUser cu = users.get(user);
                if(cu != null)
                {
                    cu.onHasKey(sender);
                }
            }
        }
    }
}